package com.auto.service.impl.coder.tree.web;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.auto.annotation.Column;
import com.auto.annotation.Table;
import com.auto.service.impl.Coder;
import com.common.ArrayUtils;
import com.common.CommonUtil;
import com.common.Global;
import com.pojo.StateInfo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.log4j.Logger;

/**
 * 处理页面所有的模板
 * @author chenfuqiang
 *
 */
public class JS_ViewAddCoder implements Coder{
	
	private final String TEMPLATE_PATH = "/tree/web/viewAdd.ftl";
	private final String CLASSTAIL = "Add.js";

	@Override
	public StateInfo coder(Configuration cfg, Map<String, Object> root, boolean isOverride) {
		StateInfo stateInfo = new StateInfo();
		try {
			String fileName =
					Global.WORKSPACEPROPATH
					+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail();
			if(!isOverride) {
				File file = new File(fileName);
				if(file.exists()) {
					stateInfo.setFlag(true);
					stateInfo.setMsg("文件已存在，不进行覆盖生成!若要覆盖，请在pojo bean 注解@AutoCode(isOverride=true)");
					Logger.getLogger(this.getClass()).info("【忽略】生成文件："+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail()+"【"+stateInfo.getMsg()+"】");
					Global.Send("【忽略】生成文件："+Global.WORKSPACEPROPATH+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail()+"【"+stateInfo.getMsg()+"】");
					return stateInfo;
				}
			}
			File file = new File(Global.WORKSPACEPROPATH
					+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName"));
			if(!file.exists()) {
				file.mkdirs();
			}
			Template template = cfg.getTemplate(this.getFtlPath(),Global.ENCODE);
			Writer out = new OutputStreamWriter(new FileOutputStream(fileName),Global.ENCODE);
			template.process(root, out);
			out.flush();
			Logger.getLogger(this.getClass()).info("生成文件："+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail());
			Global.Send("生成文件："+Global.WORKSPACEPROPATH+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail());
		} catch (Exception e) {
			e.printStackTrace();
			stateInfo.setFlag(false);
			stateInfo.setMsg(e.getMessage());
		}
		return stateInfo;
	}
	@Override
	public StateInfo decoder(Configuration cfg,Map<String,Object> root,boolean isOverride) {
		StateInfo stateInfo = new StateInfo();
		try {
			if(isOverride) {
				String fileName = Global.WORKSPACEPROPATH+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail();
				File file = new File(fileName);
				if(file.exists()) {
					Global.forceDelete(file);
				}
				Logger.getLogger(this.getClass()).info("【删除】生成文件："+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail());
				Global.Send("【删除】生成文件："+Global.WORKSPACEPROPATH+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail());
				File fileFold = new File(Global.WORKSPACEPROPATH
						+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName"));
				if(fileFold.exists()) {
					fileFold.delete();
				}
				Logger.getLogger(this.getClass()).info("【删除】生成文件夹："+this.getTargetPath()+"//"+root.get("paramName"));
				Global.Send("【删除】生成文件夹："+Global.WORKSPACEPROPATH+this.getSrcPath()+this.getTargetPath()+"//"+root.get("paramName"));
			}
		}catch(Exception e) {
			e.printStackTrace();
			stateInfo.setFlag(false);
			stateInfo.setMsg(e.getMessage());
			Logger.getLogger(this.getClass()).error("FIELD DELETE FILE : "+this.getTargetPath()+"//"+root.get("paramName")+"//"+this.getClassTail()+e.getMessage());
		}
		return stateInfo;
	}
	@Override
	public Map<String, Object> getRoot(Class<?> pojo) {
		Map<String,Object> root = new HashMap<String, Object>();
		root.put("package", Global.JS_VIEW_PACKAGE);
		root.put("beanPackage", Global.PACKAGEOFPOJO);
		root.put("daoPackage", Global.DAO_PACKAGE);
		root.put("servicePackage", Global.SERVICE_PACKAGE);
		root.put("author", Global.AUTHOR);
		root.put("className", pojo.getSimpleName());
		root.put("paramName", pojo.getSimpleName().substring(0,1).toLowerCase()+pojo.getSimpleName().substring(1));
		Table table = pojo.getAnnotation(Table.class);
		String tableName = table.name();
		if(CommonUtil.isEmpty(tableName)) {
			tableName = pojo.getSimpleName();
		}
		root.put("jsname", table.jsname());
		Field[] fields = pojo.getDeclaredFields();
		if(pojo.getSuperclass()!=null){
			Class<?> clsSup = pojo.getSuperclass();
			fields = (Field[]) ArrayUtils.addAll(fields,clsSup.getDeclaredFields());
		}
		
		List<Map<String,String>> beans = new ArrayList<Map<String,String>>();
		for(Field field : fields) {
			Column column = field.getAnnotation(Column.class);
			if(column == null||CommonUtil.isEmpty(column.jsname())) {
				continue;
			}
			
			
			String decimalPrecision = null;
			String proper = field.getName();
			String dbProper = "".equals(column.name())?proper:column.name();
			String xtype = null;
			String jstype = CommonUtil.isEmpty(column.jstype())?column.type().toUpperCase():column.jstype();
			String jsxtype = null;
			String conf = null;
			if(!CommonUtil.isEmpty(column.jsxtype())) {
				jsxtype = column.jsxtype().substring(0,column.jsxtype().indexOf("[")).trim();
				conf = column.jsxtype().substring(column.jsxtype().indexOf("[")+1,column.jsxtype().length()-1);
			}else {
				jsxtype = jstype;
			}
			
			if(jsxtype.indexOf("VARCHAR")!=-1) {
				xtype="textfield";
			}else if(jsxtype.indexOf("INT")!=-1) {
				xtype="numberfield";
				decimalPrecision = "0";
			}else if(jsxtype.indexOf("DECIMAL")!=-1) {
				xtype="numberfield";
				decimalPrecision = jstype.substring(jstype.indexOf(",")+1,jstype.length()-1);
			}else {
				xtype=jsxtype;
			}
			Map<String,String> map = new HashMap<String, String>();
			map.put("dataIndex", proper);
			map.put("dbName", dbProper);
			map.put("jsname", column.jsname());
			map.put("allowBlank", String.valueOf(column.jsAllowBlank()));
			map.put("xtype", xtype);
			map.put("conf", CommonUtil.nullToStr(conf));
			map.put("decimalPrecision", decimalPrecision);
			map.put("validator", String.valueOf(column.jsValidator()));
			beans.add(map);
		}
		root.put("beans", beans);
		return root;
	}
	@Override
	public String getTargetPath() {
		String p = this.getTargetPackage();
		String[] ps = p.split("\\.");
		if(ps == null || ps.length == 0) {
			ps = new String[1];
			ps[0] = p;
		}
		StringBuffer targetPath = new StringBuffer();
		for(String t : ps) {
			targetPath.append("//").append(t);
		}
		return targetPath.toString();
	}
	@Override
	public String getTargetPackage() {
		return Global.JS_VIEW_PACKAGE;
	}

	@Override
	public String getSrcPath() {
		return Global.JSSRCPATH;
	}

	@Override
	public String getFtlPath() {
		return this.TEMPLATE_PATH;
	}

	@Override
	public String getClassTail() {
		return this.CLASSTAIL;
	}

}
